package prototipo.server.logic.util;

import prototipo.server.logic.exception.ExceptionLogic;

public class Cnpj implements CnpjIF {

	private String cnpj;

	public Cnpj(String newCnpj) throws ExceptionLogic {
		this();
		this.setCnpj(newCnpj);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((cnpj == null) ? 0 : cnpj.hashCode());
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Cnpj))
			return false;
		Cnpj other = (Cnpj) obj;
		if (cnpj == null) {
			if (other.cnpj != null)
				return false;
		} else if (!cnpj.equals(other.cnpj))
			return false;
		return true;
	}

	public Cnpj() {

	}

	/**
	 * @return the cnpj
	 */
	public String getCnpj() {
		return cnpj;
	}

	/**
	 * @param cnpj
	 *            the cnpj to set
	 * @throws ExceptionLogic
	 */
	public void setCnpj(String cnpj) throws ExceptionLogic {
		if (validateCnpj(cnpj))
			this.cnpj = cnpj;
		else
			throw new ExceptionLogic("Cnpj invalido.", new Throwable(
					"Cnpj failed."));
	}

	private boolean validateCnpj(String str_cnpj) throws ExceptionLogic {
		if (str_cnpj == null)
			throw new ExceptionLogic("Cnpj vazio.", new Throwable(
					"String cnpj is null."));
		if (str_cnpj.length() != 14)
			throw new ExceptionLogic("Insira um cnpj valido, 14 digitos.",
					new Throwable("Cnpj String length is not 14."));
		int soma = 0, aux, dig;
		String cnpj_calc = str_cnpj.substring(0, 12);
		char[] chr_cnpj = str_cnpj.toCharArray();
		for (int i = 0; i < 4; i++)
			if (chr_cnpj[i] - 48 >= 0 && chr_cnpj[i] - 48 <= 9)
				soma += (chr_cnpj[i] - 48) * (6 - (i + 1));
		for (int i = 0; i < 8; i++)
			if (chr_cnpj[i + 4] - 48 >= 0 && chr_cnpj[i + 4] - 48 <= 9)
				soma += (chr_cnpj[i + 4] - 48) * (10 - (i + 1));
		dig = 11 - (soma % 11);
		cnpj_calc += (dig == 10 || dig == 11) ? "0" : Integer.toString(dig);
		soma = 0;
		for (int i = 0; i < 5; i++)
			if (chr_cnpj[i] - 48 >= 0 && chr_cnpj[i] - 48 <= 9)
				soma += (chr_cnpj[i] - 48) * (7 - (i + 1));
		for (int i = 0; i < 8; i++)
			if (chr_cnpj[i + 5] - 48 >= 0 && chr_cnpj[i + 5] - 48 <= 9)
				soma += (chr_cnpj[i + 5] - 48) * (10 - (i + 1));
		dig = 11 - (soma % 11);
		cnpj_calc += (dig == 10 || dig == 11) ? "0" : Integer.toString(dig);
		return str_cnpj.equals(cnpj_calc);
	}

	public String toString() {
		return String.format("%s.%s.%s/%s-%s", this.cnpj.substring(0, 2),
				this.cnpj.substring(2, 5), this.cnpj.substring(5, 8), this.cnpj
						.substring(8, 12), this.cnpj.substring(12, 14));
	}

}
